﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;

namespace Subattle
{
    public class TorpedoHandler
    {
        Random randomizer = new Random();
        Canvas parentCanvas;
        BubbleParticles bubbles;
        double torpedoTimer = 0;
        byte torpedoCounter = 0;

        public List<Torpedo> Torpedos { get; set; }
        public double TorpedoFireInterval { get; set; }
        public bool CanFireTorpedo { get { return torpedoTimer >= TorpedoFireInterval; } }

        public TorpedoHandler(Canvas parentCanvas, BubbleParticles bubbles)
        {
            Torpedos = new List<Torpedo>();
            TorpedoFireInterval = 2;
            this.bubbles = bubbles;
            this.parentCanvas = parentCanvas;
        }

        public Torpedo SpawnTorpedo(Submarine owner, Vector2 position, Vector2 velocity, byte id)
        {
            torpedoCounter = (byte)((Math.Max(id, torpedoCounter) + 1) % 254);
            Torpedo t = SpawnTorpedo(owner, position, velocity);
            t.ID = id;
            return t;
        }

        public Torpedo SpawnTorpedo(Submarine owner, Vector2 position, Vector2 velocity)
        {
            Torpedo t = new Torpedo();
            parentCanvas.Children.Insert(0, t);
            t.Visibility = Visibility.Collapsed;
            t.Position = position;
            t.Velocity = velocity;

            Vector2 direction = Vector2.Normalize(velocity);
            RotateTransform rt = new RotateTransform();
            rt.Angle = Math.Atan2(direction.Y, direction.X) * (180.0 / Math.PI);
            t.RenderTransform = rt;
            t.Owner = owner;
            Torpedos.Add(t);
            return t;
        }

        public Torpedo FireTorpedo(Submarine sub)
        {
            Torpedo newTorpedo = SpawnTorpedo(sub, sub.Position, sub.Direction * (float)sub.Speed * 5f);
            newTorpedo.ID = torpedoCounter++;
            torpedoCounter %= 254;
            torpedoTimer = 0;
            return newTorpedo;
        }

        public void Update(TimeSpan elapsed)
        {
            torpedoTimer += elapsed.TotalSeconds;
            for (int i = 0; i < Torpedos.Count; i++)
            {
                Torpedo t = Torpedos[i];
                if (t.Visibility == Visibility.Collapsed)
                    t.Visibility = Visibility.Visible;
                if (t.Position.X > 500 || t.Position.Y > 500 || t.Position.X < 0 || t.Position.Y < 0)
                {
                    parentCanvas.Children.Remove(t);
                    Torpedos.RemoveAt(i--);
                }
                else
                {
                    t.Update(elapsed);
                    Vector2 dir = Vector2.Normalize(t.Velocity);
                    dir = new Vector2(-dir.Y, dir.X);
                    Vector2 offset = dir * 2.5f;


                    if (t.Opacity > 0)
                        bubbles.SpawnBubble(t.Position + offset, new Vector2((float)(randomizer.NextDouble() * 50.0 - 25), (float)(randomizer.NextDouble() * 50 - 25)));
                }
            }

        }

        public List<Torpedo> Collision(Submarine sub)
        {
            List<Torpedo> torpedosThatHit = new List<Torpedo>();

            // Check if any torpedo has hit a submarine
            for (int i = 0; i < Torpedos.Count; i++)
            {

                Vector2 step = Vector2.Normalize(Torpedos[i].Velocity) * 7.5f;

                if (Torpedos[i].Owner != sub && sub.LazyCollision(new Vector2[] { Torpedos[i].Position, Torpedos[i].Position + step, Torpedos[i].Position - step }))
                {
                    parentCanvas.Children.Remove(Torpedos[i]);

                    torpedosThatHit.Add(Torpedos[i]);

                    Torpedos.RemoveAt(i--);
                }
            }
            return torpedosThatHit;
        }

        public void Reset()
        {
            foreach (var t in Torpedos)
            {
                parentCanvas.Children.Remove(t);
            }
            Torpedos.Clear();
        }
    }
}
